/**
 * Copyright 2011 Enjoy Change, Inc. All rights reserved.
 * Use is subject to license terms.
 */
package com.enjoychange.framework.component.storycase;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.util.Assert;

import com.enjoychange.framework.annotation.storycase.ShowStory;
import com.enjoychange.framework.annotation.storycase.Story;


/**
 * story
 * @author l90003709
 * 
 */
public class StoryTracker {
	
	//private static Logger LOG = LoggerFactory.getLogger(StoryTracker.class);
	private static Log LOG = LogFactory.getLog(StoryTracker.class);
	/**
	 * 扫描类的方法注解，是Story注解的抽取信息。
	 * @param target 类
	 * @return
	 */
    private static List<ShowStory> trackStory(final Class<?> target){
        String classname=target.toString();
        List<ShowStory> showList=new ArrayList<ShowStory>();
    	for(Method m: target.getDeclaredMethods()){
    		Story astory=m.getAnnotation(Story.class);  
    		if(astory==null){
    			continue;
    		}
    	    /*for(Type ptype:m.getGenericParameterTypes()){	}*/
    		ShowStory show=new ShowStory();    		
    		show.setStoryId(astory.storyId());
    		//com.huaweisymantec.icache.mss.device.service.ProtocolFluxQuartzJob.execute(52)|liuyang|实现策略新增    		
    		show.setDetail(classname+"."+m.getName()+"|"+astory.author()+"|"+astory.descn());
    		showList.add(show);
    	}
    	return showList;
    }
   /**
    * 抽取Story实现的信息
    * @param packagesToScan 包路径
    * @return
    */
   public static List<ShowStory> getStoryImplementsInformations(String[] packagesToScan){
		Assert.notNull(packagesToScan, "Warn,packagesToScan can not be null!");
		// 根据包路径扫描注解
		List<ShowStory> showList = new ArrayList<ShowStory>();
		for (int i = 0; i < packagesToScan.length; i++) {
			List<String> pathList = getPackagePathClass(packagesToScan[i]);
			for (String filepath : pathList) {
				try {
					List<ShowStory> scanStoryList=trackStory(getClassByAnalisePath(filepath));
					if(!scanStoryList.isEmpty()){
						showList.addAll(scanStoryList);
					}				

				} catch (Throwable e) {
					//如果出现异常，记录日志，继续循环
					LOG.error("getStoryImplementsInformations error",e);
				}

			}
		}
		return showList;
    }
    /**
     * 根据需要扫描的包路径，获取该包路径以及子路径下的所有class文件路径。
     * @param packagesToScan
     * @return
     */
     private static List<String> getPackagePathClass(String packagesToScan){   	
       if(StringUtils.isBlank(packagesToScan)){
       	throw new IllegalArgumentException("The packagesToScan can not be null or empty!");
       }
       String packagePath=packagesToScan.replace(".", "/");
   	List<String> files=getAllFiles(getDefaultClassLoader().getResource(packagePath).getPath(),new String[]{".class"});
   	return files;
   }
   /**
    * 根据class文件路径信息，解析出java类路径
    * @param filepath
    * @return
    * @throws ClassNotFoundException
    */
    private static Class<?> getClassByAnalisePath(String filepath) throws ClassNotFoundException {
		String classpath=getDefaultClassLoader().getResource("").getPath();
		String packageClass=filepath.substring(classpath.length()).replace("/", ".");		
		String packageJava=packageClass.substring(0, packageClass.length()-".class".length());	
		return Class.forName(packageJava);
	}
   
    /**
     * 获取路径下满足给定后缀范围的所有文件
     * @param absoluteDir
     * @param suffixs 后缀范围
     * @return
     */
    private static List<String> getAllFiles(String absoluteDir,String[] suffixs){   
      
        List<String> files=new ArrayList<String>();   
       
        File parentDir=new File(absoluteDir);   
      
        String []list=parentDir.list();   
        for(String s: list){   
           
            String name=absoluteDir+"/"+s;   
            File instance=new File(name);   
           
            if(instance.isFile()){ 
            	   for(int i=0;i<suffixs.length;i++){
            	   if(s.endsWith(suffixs[i])){
            		   //满足后缀名要求的才添加
            		   files.add(name);    
                      }   
            	   }
                            
            }else{   
            	
                files.addAll(getAllFiles(name,suffixs));   
            }   
        }   
        return files;   
    }
    private static ClassLoader getDefaultClassLoader() {
		ClassLoader cl = null;
		try {
			cl = Thread.currentThread().getContextClassLoader();
		}
		catch (Throwable ex) {
			// Cannot access thread context ClassLoader - falling back to system class loader...
			LOG.error("getDefaultClassLoader error",ex);
		}
		if (cl == null) {
			// No thread context class loader -> use class loader of this class.
			cl = StoryTracker.class.getClassLoader();
		}
		return cl;
	}
	public static void main(String[] arrs){
		
		//-----------------111------------:file:/F:/business/googlesvn/trunk/enjoychange/WebRoot/WEB-INF/classes/org/think/language
		//-----------------222------------:/F:/business/googlesvn/trunk/enjoychange/WebRoot/WEB-INF/classes/org/think/language
	    //File file=new File(getDefaultClassLoader().getResource("org/think/language").getPath());  
		//---------------------------------:/F:/business/googlesvn/trunk/enjoychange/WebRoot/WEB-INF/classes/
	
		List<ShowStory> showList=getStoryImplementsInformations(new String[]{"org.think.language"});
		for(ShowStory show:showList){
			
			LOG.info("-----------------the file------------:"+show.toString());
		
		}
		
	}
	
}
